﻿/*压缩类型：完全*/
/**********************************************************
功能：流程图节点对象定义
使用：
	作为流程图组件的一部分，由flowchart_panel.js自动引入
需要扩展的功能：
	修改节点属性（FlowChart_Node_ShowAttribute）
	对象属性Data的值修改
作者：叶中奇
创建时间：2005-06-01
修改记录：
	2005-06-07：完成主要的功能
**********************************************************/

//====================::::::::::流程图节点全局对象::::::::::====================

FlowChartObject.Nodes = new Object;
FlowChartObject.Nodes.all = new Array;				//节点索引
FlowChartObject.Nodes.Index;						//节点流水号
FlowChartObject.Nodes.Start = null;					//起始节点
FlowChartObject.Nodes.End = null;					//终止节点
FlowChartObject.Nodes.Image = "sp.gif";	            //默认图片
FlowChartObject.Nodes.StepGUID = "";                //步骤GUID

//新建节点，并移动到当前光标下
FlowChartObject.Nodes.New = function()
{
	var newNode = new FlowChart_Node();
	var xx = event.x + document.body.scrollLeft - newNode.GetWidth()/2;
	var yy = event.y + document.body.scrollTop - newNode.GetHeight()/2;

	newNode.MoveTo(xx, yy, true);
};

FlowChartObject.Nodes.InfoBox = new Object;			//详细信息框
FlowChartObject.Nodes.InfoBox.Visible = false;		//详细信息框是否可见
FlowChartObject.Nodes.InfoBox.DOMElement = null;	//详细信息框的DOM对象

//显示详细信息框，由图片点击事件触发
FlowChartObject.Nodes.InfoBox.ShowInfo = function()
{
	setNodeText(this.LKSObject.StepGUID);
	//this指图片的input标签对象
	var DOMObj = FlowChartObject.Nodes.InfoBox.DOMElement;
	if(this.LKSObject.Title=="")
	{
		DOMObj.style.display = "none";
		FlowChartObject.Nodes.InfoBox.Visible = false;
	}else
	{
		DOMObj.rows[0].cells[0].innerHTML = this.LKSObject.Title;
		DOMObj.style.display = "";
		//将信息框显示在当前节点的旁边，并不让显示框超出边界
		var x = this.LKSObject.DOMElement.clientWidth;
		if(this.LKSObject.Left+x+4+DOMObj.clientWidth>document.body.clientWidth+document.body.scrollLeft)
			DOMObj.style.left = this.LKSObject.Left-DOMObj.clientWidth-4;
		else
			DOMObj.style.left = this.LKSObject.Left+x+4;
		if(this.LKSObject.Top+DOMObj.clientHeight>document.body.clientHeight+document.body.scrollTop)
			DOMObj.style.top = this.LKSObject.Top+this.LKSObject.DOMElement.clientHeight-DOMObj.clientHeight;
		else
			DOMObj.style.top = this.LKSObject.Top;
		FlowChartObject.Nodes.InfoBox.Visible = true;
	}
};

//隐藏详细信息框
FlowChartObject.Nodes.InfoBox.Hide = function()
{
	if(FlowChartObject.Nodes.InfoBox.Visible && event.srcElement.id!="NodeImages")
	{
		FlowChartObject.Nodes.InfoBox.DOMElement.style.display = "none";
		FlowChartObject.Nodes.InfoBox.Visible = false;
	}
};

//节点初始化操作，创建详细显示框的HTML对象，创建开始和结束节点
FlowChartObject.Nodes.Initialize = function()
{
	var htmlCode = "<table class=flownodeinfo_tb style='position:absolute; display:none' />";"";

	var newElem = document.createElement(htmlCode);
	newElem.insertRow(-1).insertCell(-1);
	newElem.rows[0].cells[0].className = "flownodeinfo_td";
	document.body.appendChild(newElem);
	FlowChartObject.Nodes.InfoBox.DOMElement = newElem;
	newElem.LKSObject = FlowChartObject.Nodes.InfoBox;
	LKSEvent.AddEvent("onmousedown", FlowChartObject.Nodes.InfoBox.Hide);
	
	
	/* sbb11 系统不自动生成开始节点和结束节点
	var node = new FlowChart_Node("start");
	var x = Math.round((document.body.clientWidth-node.GetWidth())/2);
	node.MoveTo(x, 20, true);
	node = new FlowChart_Node("end");
	node.MoveTo(x, 120, true);
	FlowChartObject.Nodes.Index = 0;
	*/
};

//====================::::::::::流程图节点对象::::::::::====================
function FlowChart_Node(NodeType, NodeText, NodeImg)
{
	//==========初始校验==========
	switch(NodeType)
	{
		case "start":
		if(FlowChartObject.Nodes.Start!=null)
			throw "开始节点只能有一个";
		FlowChartObject.Nodes.Start = this;
		NodeText = NodeText?NodeText:"开始";
		NodeImg = NodeImg?NodeImg:"initstep.gif";
		break;
		
		case "end":
		if(FlowChartObject.Nodes.End!=null)
			throw "结束节点只能有一个";
		FlowChartObject.Nodes.End = this;
		NodeText = NodeText?NodeText:"结束";
		NodeImg = NodeImg?NodeImg:"endstep.gif";
		break;
		
		case "sp":
		NodeImg = NodeImg?NodeImg:"sp.gif";
		break;
		
		case "hq":
		NodeImg = NodeImg?NodeImg:"hq.gif";
		break;
		
	}
	
	//==========属性==========
	this.Name = "Node";														//对象名称
	this.Type = NodeType?NodeType:"sp";									    //类型：sp（审批）；hq(会签);start（开始）；end（结束）
	this.TypeName = this.Type=="sp"?"审批":(this.Type=="hq"?"会签":(this.Type=="start"?"开始":"结束"));	
	this.Top = 0;															//纵坐标
	this.Left = 0;															//横坐标
	//this.Text = NodeText?NodeText:"节点"+(++FlowChartObject.Nodes.Index);	//节点文本
	this.Text = "新建步骤";													//sbb11 步骤文本
	this.Title = "";														//节点标题
	this.Image = NodeImg?NodeImg:FlowChartObject.Nodes.Image;				//节点图片，IsEnabled=true时显示图片Image+"_1.gif"，IsEnabled=false时显示Image+"_2.gif"
	this.IsSelected = false;												//是否被选中
	this.CanDelete = this.Type=="sp"?true:(this.Type=="hq"?true:false);						//是否可以被删除
	this.CanLinkStart = this.Type!="end"?true:false;						//是否可以接入连线起点
	this.CanLinkEnd = this.Type!="start"?true:false;						//是否可以接入连线终点
	this.CanChgAttribute = true;                                            //是否可以修改属性
	this.StepGUID = "";										
	

	
	//==========子对象==========
	this.Data = new Object;														//节点数据，用于扩充
	this.LineStart = new Array;												//起点为当前节点的连线
	this.LineEnd = new Array;												//终点为当前节点的连线
		
	//==========方法==========
	this.GetWidth = FlowChart_Node_GetWidth;								//获取节点宽度
	this.GetHeight = FlowChart_Node_GetHeight;								//获取节点高度
	this.SetText = FlowChart_Node_SetText;									//设置文本
	this.SetTitle = FlowChart_Node_SetTitle;								//设置标题
	this.SetImage = FlowChart_Node_SetImage;								//设置图片
	this.SetFunction = FlowChart_Node_SetFunction;							//设置功能
	this.MoveTo = FlowChart_Node_MoveTo;									//移动节点
	this.Select = FlowChart_Node_Select;									//选中节点
	this.GetPointXY = FlowChart_Node_GetPointXY;							//获取操作点的位置
	this.ShowAttribute = FlowChart_Node_ShowAttribute;						//显示属性
	this.Delete = FlowChart_Node_Delete;									//删除节点
	this.AddLineStart = FlowChart_Node_AddLineStart;						//添加连线起点
	this.AddLineEnd = FlowChart_Node_AddLineEnd;							//添加连线终点
	this.DelLineStart = FlowChart_Node_DelLineStart;						//删除连线起点
	this.DelLineEnd = FlowChart_Node_DelLineEnd;							//删除连线终点
	
		
	//==========初始化==========
	//外框部分，用于显示阴影效果
	var htmlCode = "<table border=0 cellpadding=0 cellspacing=0 style='position:absolute;' id=NodeElements class=flownode_top />";
	var newElem = document.createElement(htmlCode);
	document.body.appendChild(newElem);
	newElem.insertRow(-1).insertCell(-1);
	newElem.insertRow(-1).insertCell(-1);
	newElem.insertRow(-1).insertCell(-1);
	newElem.rows[0].insertCell(-1);
	newElem.rows[2].insertCell(-1);
	newElem.rows[2].insertCell(-1);
	newElem.rows[2].insertCell(-1);
	newElem.rows[0].cells[0].colSpan = 2;
	newElem.rows[0].cells[0].rowSpan = 2;
	newElem.rows[0].cells[0].className = "flownode_main_out";			//主显示区域
	newElem.rows[0].cells[1].className = "flownode_sd_blank";			//右上角空白部分
	newElem.rows[1].cells[0].className = "flownode_sd_black_r";			//右边阴影部分
	newElem.rows[2].cells[0].className = "flownode_sd_blank";			//左下角空白部分
	newElem.rows[2].cells[1].className = "flownode_sd_black_b";			//下边阴影部分
	newElem.rows[2].cells[2].className = "flownode_sd_black_rb";		//右下角阴影部分
	this.DOMElement = newElem;
	newElem.LKSObject = this;
	
	var nodestatus = ""; 
	try
	{
		nodestatus = parent.xmlDom.selectNodes("//Step")(FlowChartObject.Nodes.all.length).selectSingleNode("Attributes/StepStatus").text;
		this.StepGUID = parent.xmlDom.selectNodes("//Step")(FlowChartObject.Nodes.all.length).selectSingleNode("Attributes/StepGUID").text;
	}
	catch(e){}
	
	if ( nodestatus=="1" || nodestatus=="2")
	{
		htmlCode = "<table class=flownode_main_active />";              //待办在办节点(橙色)
	}
	else if (nodestatus=="0" || nodestatus=="" )
	{
		htmlCode = "<table class=flownode_main_nor />";                 //未激活节点(淡黄)
	}
	else
	{
		htmlCode = "<table class=flownode_main_close />";               //其它关闭节点(绿色)
	}
	//end modified by xug 2008-05-30
	
	//htmlCode = "<table class=flownode_main_nor />";
	newElem = document.createElement(htmlCode);
	newElem.onclick = FlowChartObject.Nodes.InfoBox.ShowInfo;           //点击显示详细信息框
	newElem.style.cursor = "hand";
	newElem.LKSObject = this;
	
	this.DOMElement.rows[0].cells[0].appendChild(newElem);
	newElem.insertRow(-1).insertCell(-1);								//第一个单元格显示图片
	newElem.rows[0].insertCell(-1);										//第二个单元格显示文字
	newElem.rows[0].cells[0].width = 1;
	newElem.rows[0].cells[0].className = "flownode_text";	
	newElem.rows[0].cells[1].className = "flownode_type";
	
	newElem.insertRow(-1).insertCell(-1);                               //sbb11 插入步骤类型
	newElem.rows[1].cells[0].className = "flownode_text";
	newElem.rows[1].cells[0].colSpan = 2;

	
	
	this.DOMMain = newElem;
	//图片区域
	htmlCode = "<input type=image id=NodeImages />";
	newElem = document.createElement(htmlCode);
	this.DOMMain.rows[0].cells[0].appendChild(newElem);
	this.DOMImage = newElem;	

	this.DOMMain.rows[0].cells[1].innerHTML=this.TypeName;	

	
	//文字区域
	this.DOMText = this.DOMMain.rows[1].cells[0];
	
	
	this.SetText();
	this.SetImage();


    if (FlowChartObject.Nodes.all.length!=0)
    {
        if (FlowChartObject.Nodes.all[FlowChartObject.Nodes.all.length - 1].Type=="end")
        {
           FlowChartObject.Nodes.all[FlowChartObject.Nodes.all.length] = FlowChartObject.Nodes.all[FlowChartObject.Nodes.all.length - 1];
           FlowChartObject.Nodes.all[FlowChartObject.Nodes.all.length - 2] = this;
        }
        else
        {
            FlowChartObject.Nodes.all[FlowChartObject.Nodes.all.length] = this;
        }
    }
    else
    {
       FlowChartObject.Nodes.all[FlowChartObject.Nodes.all.length] = this;
    }
	
}

//====================::::::::::流程图节点函数::::::::::====================

//获取节点宽度
function FlowChart_Node_GetWidth()
{
	return this.DOMElement.clientWidth;
}

//获取节点高度
function FlowChart_Node_GetHeight()
{
	return this.DOMElement.clientHeight;
}

//设置文本，若不传参数，则采用当前值
function FlowChart_Node_SetText(NodeText)
{
	if(NodeText!=null)
		this.Text = NodeText;
	this.DOMText.innerHTML = this.Text;
}

//设置标题，若不传参数，则采用当前值
function FlowChart_Node_SetTitle(NodeTitle)
{
	if(NodeTitle!=null)
		this.Title = NodeTitle;
}

//设置图片，若不传参数，则采用当前值
function FlowChart_Node_SetImage(NodeImage)
{
	if(NodeImage!=null)
	{
		if(this.Image==NodeImage)
			return;
		this.Image = NodeImage;
	}
	this.DOMImage.src = S_ResourcePath+"images/"+this.Image;
}



/****************************************************************************************
功能：设置功能权限
参数：
	funcName：节点对象中以"Can"开头的属性，如："Delete"表示设置节点"CanDelete"属性
	value：true或false，为空则不修改原有属性
****************************************************************************************/
function FlowChart_Node_SetFunction(funcName, value)
{
	if(eval("this.Can"+funcName)==null)
		throw "参数设置无效";
	else
		if(value!=null)
			eval("this.Can"+funcName+"=value;");
}

/**********************************************************
功能：移动节点，同时移动节点的连线
参数：
	x：横坐标，不指定则取原有值
	y：纵坐标，不指定则取原有值
	toGrid：true（吸附到网格），默认为false
**********************************************************/
function FlowChart_Node_MoveTo(x, y, toGrid)
{
	if(x!=null)
		this.Left = x;
	if(y!=null)
		this.Top = y;
	if(toGrid)
	{
		this.Left = Math.round(this.Left/FlowChartObject.Grid.Width)*FlowChartObject.Grid.Width;
		this.Top = Math.round(this.Top/FlowChartObject.Grid.Width)*FlowChartObject.Grid.Width;
	}
	this.DOMElement.style.top = this.Top;
	this.DOMElement.style.left = this.Left;
	var i;
	for(i=0; i<this.LineStart.length; i++)
		this.LineStart[i].Refresh();
	for(i=0; i<this.LineEnd.length; i++)
		this.LineEnd[i].Refresh();
}

/********************************************************************
功能：选中节点
参数：
	selType：true（选中）；false（不选中）；null（反向选中）
********************************************************************/
function FlowChart_Node_Select(selType)
{
	this.IsSelected = (selType==null)?!this.IsSelected:selType;
	
	//modified by xug 2008-05-30
	//if(FlowChartObject.IsEdited)
	if(FlowChartObject.IsEdited && this.CanChgAttribute)
		this.DOMMain.className = this.IsSelected?"flownode_main_sel":"flownode_main_nor";
}

/********************************************************************
功能：获取操作点的位置
参数：
	position：位置，值为：NodeTop、NodeBottom、NodeLeft、NodeRight
********************************************************************/
function FlowChart_Node_GetPointXY(position)
{
	var width = this.DOMMain.clientWidth;
	var height = this.DOMMain.clientHeight;
	switch(position)
	{
		case "NodeTop":
		return new Array(this.Left+width/2, this.Top);
		
		case "NodeBottom":
		return new Array(this.Left+width/2, this.Top+height);
		
		case "NodeLeft":
		return new Array(this.Left, this.Top+height/2);
		
		case "NodeRight":
		return new Array(this.Left+width, this.Top+height/2);
	}
}

//显示属性，该功能一般由其他的JS编写替换代码
function FlowChart_Node_ShowAttribute()
{
	if(this.CanChgAttribute)
		alert("显示步骤属性："+this.Text);
}

/**********************************************************
功能：删除节点，同时删除相关的连线
参数：
	force：true（强制删除），false（默认）
**********************************************************/
function FlowChart_Node_Delete(force)
{
	if(!force && !this.CanDelete)
		return;
	for(; this.LineStart.length>0;)
		this.LineStart[0].Delete(true);
	for(; this.LineEnd.length>0; )
		this.LineEnd[0].Delete(true);
	FlowChartObject.Nodes.all = FlowChartObject.Nodes.all.removeElem(this);
	this.DOMElement.removeNode(true);
}

//添加连线起点
function FlowChart_Node_AddLineStart(line)
{
	if(this.LineStart.indexOf(line)==-1)
		this.LineStart[this.LineStart.length] = line;
}

//添加连线终点
function FlowChart_Node_AddLineEnd(line)
{
	if(this.LineEnd.indexOf(line)==-1)
		this.LineEnd[this.LineEnd.length] = line;
}

//删除连线起点
function FlowChart_Node_DelLineStart(line)
{
	this.LineStart = this.LineStart.removeElem(line);
}

//删除连线终点
function FlowChart_Node_DelLineEnd(line)
{
	this.LineEnd = this.LineEnd.removeElem(line);
}
